package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.enums.*;
import cn.huiyunche.base.service.interfaces.*;
import cn.huiyunche.base.service.mappers.BScoresMapper;
import cn.huiyunche.base.service.mappers.ext.BScoresViewMapper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.vo.*;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.lang.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 积分余额接口实现类
 *
 * @author lm
 */
@Service
public class BScoresServiceImpl implements BScoresService {

    private static final Logger LOGGER = LoggerFactory.getLogger(BScoresServiceImpl.class);

    private static final int BIGDECIMAL_POINT = 2;

    private static final int BIGDECIMAL_TYPE = BigDecimal.ROUND_UP;

    // 25分 兑换 1元
    private static final BigDecimal QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT = new BigDecimal("100");

    // 订单兑换 金额边界
    private static final BigDecimal ORDER_COST_BOUNDARY = new BigDecimal("2000");

    // 订单最大兑换比例
    private static final BigDecimal ORDER_COST_RATE = new BigDecimal("0.10");

    // 当订单金额大于2000 则每辆车抵扣200
    private static final BigDecimal ORDER_COST_MAXEXANGE = new BigDecimal("200").setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);

    // 托运企业月对账的时候 最多抵扣积分规则待结算金额的10%
    // private static final BigDecimal KyleCompany_MonthBill_MaxRate = new BigDecimal("0.1");

    // 托运企业月对账的时候 抵扣积分最多抵扣1000元／月
    private static BigDecimal KyleCompany_MonthBill_MaxAmount = new BigDecimal("500").setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);

    // 提现最大兑换 金额
    private static final BigDecimal QUICKWITHDRAW_SCORES_MAXEXCHANGE = new BigDecimal("50").setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);

    // 提现最大兑换比例
    private static final BigDecimal QUICKWITHDRAW_FEE_MAXEXCHANGE = new BigDecimal("0.1");

    @Autowired
    private BScoresMapper bScoresMapper = null;

    @Autowired
    private BScoresViewMapper bScoresViewMapper = null;

    @Autowired
    private BScoresTurnoverService bScoresTurnoverService = null;

    @Autowired
    private UserService userService = null;

    @Autowired
    private BScoresLevelService bScoresLevelService = null;

    @Autowired
    private BActivityService bActivityService;

    @Autowired
    private CAccntBillService cAccntBillService = null;

    @Autowired
    private BCompanyUserService bCompanyUserService = null;

    @Autowired
    private CompanyService CompanyService = null;

    private CompanyService getCompanyService() {
        return this.CompanyService;
    }

    private BCompanyUserService getBCompanyUserService() {
        return this.bCompanyUserService;
    }

    private CAccntBillService getCAccntBillService() {
        return this.cAccntBillService;
    }

    private BScoresViewMapper getBScoresViewMapper() {
        return this.bScoresViewMapper;
    }

    private BScoresMapper getBScoresMapper() {
        return this.bScoresMapper;
    }

    private BScoresTurnoverService getBScoresTurnoverService() {
        return this.bScoresTurnoverService;
    }

    private UserService getUserService() {
        return this.userService;
    }

    private BScoresLevelService getBScoresLevelService() {
        return this.bScoresLevelService;
    }

    // 查询当前登录用户
    public UserShowVo getUserShowVo() {
        try {
            return this.getUserService().getCurrentUser();
        } catch (Exception e) {
            LOGGER.error("select current user ERROR : {}.", e);
            throw new BusinessException("查询当前登录用户异常");
        }
    }

    /**
     * 用户注册 增加积分余额
     * －－ 用户注册(4类)
     * －－ 用户下单 使用积分－扣除 2
     *
     * @param bScores
     * @return
     */
    @Override
    public int addScores(BScores bScores) {
        LOGGER.info("insert one bScores params bScores : {}.", bScores);
        try {
            return this.getBScoresViewMapper().insertSelective(bScores);
        } catch (Exception e) {
            LOGGER.error("insert one bScores params bScores : {}, error : {}.", JSON.toJSONString(bScores), e);
            throw new BusinessException("单条增加积分余额异常");
        }
    }

    /**
     * 根据当前登录用户
     * 查询积分 scores
     * 查询积分明细 turnover
     * －－ 托运企业
     *
     * @return
     */
    @Override
    public Map<String, Object> getScoresAndTurnover(PageVo page) {
        LOGGER.info("getScoresAndTurnover params : {}", page);
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            // 查询当前用户
            UserShowVo userShowVo = this.getUserShowVo();
            LOGGER.info("select current user userShowVo : {}.", JSON.toJSONString(userShowVo));
            if (null == userShowVo) {
                LOGGER.info("select current user is not exist userShowVo : {}.", JSON.toJSONString(userShowVo));
                throw new BusinessException("当前登录账户不存在");
            }

            LOGGER.info("select user scores userShowVo : {}.", JSON.toJSONString(userShowVo));
            BScoresExample scoresExample = new BScoresExample();
            Long userId = userShowVo.getId();
            Integer userType = userShowVo.getUserType();
            if (userType == UserTypeEnum.COMPANY.getValue() || userType == UserTypeEnum.SCOMPANY.getValue()) {
                userId = this.getBCompanyUserService().getCompanyIdByUserId(userId);
            }
            scoresExample.createCriteria().andUserIdEqualTo(userId).andUserTypeEqualTo(userType);
            List<BScores> bScoresList = this.getBScoresMapper().selectByExample(scoresExample);
            if (!Collections.isEmpty(bScoresList)) {
                BScores bScores = bScoresList.get(0);
                LOGGER.info("select user scores scores : {}, userShowVo : {}.", bScores.getScores(), JSON.toJSONString(userShowVo));
                map.put("scores", bScores.getScores());

                LOGGER.info("select user scores turnover params userId : {}, userType : {}.", userId, userType);
                Map<String, Object> mapTurnover = this.getBScoresTurnoverService().selectTurnoversByUser(userShowVo, page);
                map.put("turnover", mapTurnover.get("turnovers"));
                map.put("page", mapTurnover.get("page"));

                return map;
            }
        } catch (Exception e) {
            LOGGER.error("select user scores ERROR : {}.", e);
            throw new BusinessException("查询用户积分余额异常");
        }

        map.put("scores", BigDecimal.ZERO);
        map.put("turnover", null);
        map.put("page", page);
        return map;
    }

    /**
     * 根据当前登录用户
     * 查询积分 scores
     * －－ 托运企业
     *
     * @return
     */
    @Override
    public BigDecimal getScores() {
        try {
            // 查询当前用户
            UserShowVo userShowVo = this.getUserShowVo();
            LOGGER.info("select current user userShowVo : {}.", JSON.toJSONString(userShowVo));
            if (null == userShowVo) {
                LOGGER.info("select current user is not exist userShowVo : {}.", JSON.toJSONString(userShowVo));
                throw new BusinessException("当前登录账户不存在");
            }

            LOGGER.info("select user scores userShowVo : {}.", JSON.toJSONString(userShowVo));
            BScoresExample scoresExample = new BScoresExample();
            Long userId = userShowVo.getId();
            Integer userType = userShowVo.getUserType();
            if (userType == UserTypeEnum.SCOMPANY.getValue() || userType == UserTypeEnum.COMPANY.getValue()) {
                userId = this.getBCompanyUserService().getCompanyIdByUserId(userId);
            }
            scoresExample.createCriteria().andUserIdEqualTo(userId).
                    andUserTypeEqualTo(userType);
            List<BScores> bScoresList = this.getBScoresMapper().selectByExample(scoresExample);
            if (!Collections.isEmpty(bScoresList)) {
                BScores bScores = bScoresList.get(0);
                LOGGER.info("select user scores scores : {}, userShowVo : {}.", bScores.getScores(), JSON.toJSONString(userShowVo));
                return bScores.getScores();
            }
        } catch (Exception e) {
            LOGGER.error("select user scores ERROR : {}.", e);
            throw new BusinessException("查询用户积分余额异常");
        }
        return BigDecimal.ZERO;
    }

    /**
     * 根据当前登录用户
     * 查询积分流水 scoresTurnover
     * －－ 托运企业
     *
     * @return
     */
    @Override
    public Map<String, Object> getScoresTurnover(PageVo page) {
        LOGGER.info("select user scores turnover params page : {}.", page);
        return this.getBScoresTurnoverService().selectTurnoversByCurrent(page);
    }

    /**
     * 添加 用户总里程数 接口
     *
     * @param cWaybill
     * @param distance
     * @return
     */
    @Override
    public int addTotalDistance(CWaybill cWaybill, BigDecimal distance) {
        LOGGER.info("insert or update user total distance params cWaybill : {}, distance : {}.", cWaybill, distance);
        try {
            Long userId = cWaybill.getBidderId();
            SUser user = this.getUserService().selectByPrimaryKey(userId);
            Integer userType = user.getUserType();

            BScoresExample example = new BScoresExample();
            example.createCriteria().andUserIdEqualTo(userId).andUserTypeEqualTo(userType);
            List<BScores> bScoresList = this.getBScoresMapper().selectByExample(example);
            BScores bScores = null;
            if (!Collections.isEmpty(bScoresList)) {
                bScores = bScoresList.get(0);
                BScoresLevel level = this.getBScoresLevelService().selectByLevel(userType, bScores.getDistanceTotal());
                if (level == null) {
                    LOGGER.info("insert or update user total distance not exists level userType : {}.", userType);
                    throw new BusinessException("未查询到此类用户的用户等级");
                }
                BigDecimal score = level.getScore();
                bScores.setDistanceTotal(bScores.getDistanceTotal().add(distance));
                bScores.setScores(bScores.getScores().add(distance.multiply(score).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE)));
                bScores.setScoresTotal(bScores.getScoresTotal().add(distance.multiply(score).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE)));
            } else {
                bScores = new BScores();
                bScores.setUserId(userId);
                bScores.setUserName(user.getRealName());
                bScores.setUserType(userType);
                bScores.setDistanceTotal(distance);
                bScores.setScores(distance);
                bScores.setScoresTotal(distance);
            }

            // 查询等级 更新用户表user_level
            BScoresLevel level = this.getBScoresLevelService().selectByLevel(userType, bScores.getDistanceTotal());
            if (level == null) {
                LOGGER.info("insert or update user total distance not exists level userType : {}.", userType);
                throw new BusinessException("未查询到此类用户的用户等级");
            }
            bScores.setLevelId(level.getId());
            bScores.setLevel(level.getLevel());
            bScores.setLevelName(level.getLevelName());

            user.setUserLevel(level.getLevel());
            int count = this.getUserService().updateByRecord(user);
            LOGGER.info("update user level count : {].", count);

            // 添加积分明细
            BScoresTurnover bScoresTurnover = new BScoresTurnover();
            bScoresTurnover.setBusinessId(cWaybill.getId());
            bScoresTurnover.setBusinessType(AccPaytypeEnum.ORDER.getValue());
            bScoresTurnover.setCost(BigDecimal.ZERO);
            bScoresTurnover.setCreateTime(new Date());
            bScoresTurnover.setUpdateTime(new Date());
            bScoresTurnover.setIsused(true);
            bScoresTurnover.setScore(bScores.getScores());
            bScoresTurnover.setUserId(userId);
            bScoresTurnover.setUserName(user.getRealName());
            bScoresTurnover.setUserType(userType);
            this.getBScoresTurnoverService().insert(bScoresTurnover, false);

            return this.getBScoresViewMapper().insertLevelSelective(bScores);
        } catch (Exception e) {
            LOGGER.error("insert or update user total distance error.", e);
            throw new BusinessException("添加用户里程数异常");
        }
    }

    /**
     * 添加用户 里程数 接口
     *
     * @param userId   用户ID
     * @param userType 用户名称
     * @param distance 距离
     * @return
     */
    @Override
    public int addTotalDistance(Long userId, Integer userType, BigDecimal distance) {
        LOGGER.info("insert or update user total distance params userId : {}, userType : {}, distance : {}.", userId, userType, distance);
        try {
            SUser user = this.getUserService().selectByPrimaryKey(userId);

            BScoresExample example = new BScoresExample();
            example.createCriteria().andUserIdEqualTo(userId).andUserTypeEqualTo(userType);
            List<BScores> bScoresList = this.getBScoresMapper().selectByExample(example);
            BScores bScores = null;
            if (!Collections.isEmpty(bScoresList)) {
                bScores = bScoresList.get(0);
                bScores.setDistanceTotal(bScores.getDistanceTotal().add(distance));
            } else {
                bScores = new BScores();
                bScores.setUserId(userId);
                bScores.setUserName(user.getRealName());
                bScores.setUserType(userType);
                bScores.setDistanceTotal(distance);
            }

            // 查询等级 更新用户表user_level
            BScoresLevel level = this.getBScoresLevelService().selectByLevel(userType, bScores.getDistanceTotal());
            if (level == null) {
                LOGGER.info("insert or update user total distance not exists level userType : {}.", userType);
                throw new BusinessException("未查询到此类用户的用户等级");
            }
            bScores.setLevelId(level.getId());
            bScores.setLevel(level.getLevel());
            bScores.setLevelName(level.getLevelName());

            user.setUserLevel(level.getLevel());
            int count = this.getUserService().updateByRecord(user);
            LOGGER.info("update user level count : {].", count);

            return this.getBScoresViewMapper().insertLevelSelective(bScores);

        } catch (Exception e) {
            LOGGER.error("insert or update user total distance error.", e);
            throw new BusinessException("添加用户里程数异常");
        }
    }

    /**
     * 添加用户 总消费金额 接口
     *
     * @param orderId
     * @param userId
     * @param userType
     * @param cost
     * @return
     */
    @Override
    public int addTotalCost(Long orderId, Long userId, Integer userType, BigDecimal cost) {
        LOGGER.info("insert or update user total cost params : orderId: {}, userId : {}, userType : {}, cost : {}.", orderId, userId, userType, cost);
        try {
            SUser user = new SUser();
            if (userType == UserTypeEnum.COMPANY.getValue() || userType == UserTypeEnum.SCOMPANY.getValue()) {
                /** Long companyId = this.getBCompanyUserService().getCompanyIdByUserId(userId);
                 Map<String, Object> map = this.getCompanyService().selectById(companyId);
                 BCompany company = (BCompany) map.get("companyData"); */
                Map<String, Object> map = this.getCompanyService().selectById(userId);
                BCompany company = (BCompany) map.get("companyData");
                user.setRealName(company.getCompanyName());
            } else {
                user = this.getUserService().selectByPrimaryKey(userId);
            }

            BScoresExample example = new BScoresExample();
            example.createCriteria().andUserIdEqualTo(userId).andUserTypeEqualTo(userType);
            List<BScores> bScoresList = this.getBScoresMapper().selectByExample(example);
            BScores bScores = null;
            BScoresLevel level = null;
            BigDecimal scores = BigDecimal.ZERO;
            if (!Collections.isEmpty(bScoresList)) {
                bScores = bScoresList.get(0);
                // 查询等级 更新用户表user_level
                level = this.getBScoresLevelService().selectByLevel(userType, bScores.getCostTotal());
                if (level == null) {
                    LOGGER.info("insert or update user total cost not exists level userType : {}.", userType);
                    throw new BusinessException("未查询到此类用户的用户等级");
                }
                BigDecimal score = level.getScore();
                scores = cost.multiply(score).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
            } else {
                bScores = new BScores();

                // 查询等级 更新用户表user_level
                level = this.getBScoresLevelService().selectByLevel(userType, UserLevelEnum.LEVEL_A.getValue());
                if (level == null) {
                    LOGGER.info("insert or update user total cost not exists level userType : {}.", userType);
                    throw new BusinessException("未查询到此类用户的用户等级");
                }
                BigDecimal score = level.getScore();
                scores = cost.multiply(score).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
            }
            bScores.setUserId(userId);
            bScores.setUserName(user.getRealName());
            bScores.setUserType(userType);
            bScores.setCostTotal(cost);

            bScores.setScores(scores);
            bScores.setScoresTotal(scores);
            bScores.setLevelId(level.getId());
            bScores.setLevel(level.getLevel());
            bScores.setLevelName(level.getLevelName());

            if (userType == UserTypeEnum.OWNER.getValue() || userType == UserTypeEnum.DRIVER.getValue()) {
                user.setUserLevel(level.getLevel());
                int count = this.getUserService().updateByRecord(user);
                LOGGER.info("update user level count : {}.", count);
            }

            // 添加积分明细
            BScoresTurnover bScoresTurnover = new BScoresTurnover();
            bScoresTurnover.setBusinessId(orderId);
            bScoresTurnover.setBusinessType(AccPaytypeEnum.ORDER.getValue());
            bScoresTurnover.setCost(BigDecimal.ZERO);
            bScoresTurnover.setCreateTime(new Date());
            bScoresTurnover.setUpdateTime(new Date());
            bScoresTurnover.setIsused(true);
            bScoresTurnover.setScore(bScores.getScores());
            bScoresTurnover.setUserId(userId);
            bScoresTurnover.setUserName(user.getRealName());
            bScoresTurnover.setUserType(userType);
            this.getBScoresTurnoverService().insert(bScoresTurnover, false);

            return this.getBScoresViewMapper().insertLevelSelective(bScores);

        } catch (Exception e) {
            LOGGER.error("insert or update user total cost error.", e);
            throw new BusinessException("添加用户总消费金额异常");
        }
    }

    /**
     * 查询用户当前积分余额
     *
     * @param userId
     * @param userType
     * @return
     */
    @Override
    public BScores getUserScores(Long userId, int userType) {
        LOGGER.info("select user scores by userId : {}, userType : {}.", userId, userType);

        BScoresExample example = new BScoresExample();
        if (userType == UserTypeEnum.COMPANY.getValue() || userType == UserTypeEnum.SCOMPANY.getValue()) {
            userId = this.getBCompanyUserService().getCompanyIdByUserId(userId);
            if (null == userId) {
                LOGGER.error("BScoresServiceImpl.getUserScores userId is null");
                throw new BusinessException("查询用户公司信息失败");
            }
        }
        example.createCriteria().andUserIdEqualTo(userId).andUserTypeEqualTo(userType);
        List<BScores> bScores = this.getBScoresMapper().selectByExample(example);
        if (!Collections.isEmpty(bScores)) {
            return bScores.get(0);
        }

        return null;
    }

    /**
     * 查询用户订单 积分可抵扣金额
     * -- 托运个人下单
     *
     * @param customerOrderid 客户订单ID
     * @param userId          用户ID
     * @param userType        用户类型
     * @param totalCost       订单金额(提车费＋交车费＋运费＋保险费＋折扣)
     * @return
     */
    @Override
    public QueryScoresVo computeOrderAmountByScores(Long customerOrderid, Long userId, Integer userType, BigDecimal totalCost) {
        LOGGER.info("select order scores params : customerOrderid:{}, userId : {}, userType : {}, totalCost : {}.", customerOrderid, userId, userType, totalCost);
        QueryScoresVo vo = new QueryScoresVo();
        vo.setOrderId(customerOrderid);
        BigDecimal scores = BigDecimal.ZERO.setScale(BIGDECIMAL_POINT); // 使用积分0.00
        BigDecimal amount = BigDecimal.ZERO.setScale(BIGDECIMAL_POINT); // 可抵扣金额0.00
        try {
            BScores userScores = this.getUserScores(userId, userType);
            LOGGER.info("select order scores params userId : {}, userType : {}, totalCost : {}, userScores : {}.", userId, userType, totalCost, JSON.toJSONString(userScores));
            if (!(userScores == null)) {
                // 当前积分余额
                BigDecimal currentScores = userScores.getScores();
                if (totalCost.compareTo(ORDER_COST_BOUNDARY) != 1) {
                    // 可抵用的钱
                    BigDecimal willAmount = totalCost.multiply(ORDER_COST_RATE).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                    // 可抵用的钱 ＊ 积分
                    BigDecimal willScores = willAmount.multiply(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                    if (willScores.compareTo(userScores.getScores()) != 1) {
                        scores = willScores;
                        amount = willAmount;
                    } else {
                        scores = currentScores;
                        amount = currentScores.divide(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT, BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                    }
                } else {
                    // 可抵用的钱
                    BigDecimal willAmount = ORDER_COST_MAXEXANGE;
                    // 可抵用的钱 ＊ 积分
                    BigDecimal willScores = ORDER_COST_MAXEXANGE.multiply(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT).setScale(BIGDECIMAL_TYPE, BIGDECIMAL_POINT);
                    if (willScores.compareTo(userScores.getScores()) == -1) {
                        scores = willScores;
                        amount = willAmount;
                    } else {
                        scores = currentScores;
                        amount = currentScores.divide(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT, BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                    }
                }
            }

            // 用户下单保存计算的积分，如果用户使用积分付款 则查询记录扣除金额
            if (scores.compareTo(BigDecimal.ZERO) == 1 && amount.compareTo(BigDecimal.ZERO) == 1) {
                BScoresTurnover bScoresTurnover = new BScoresTurnover();
                bScoresTurnover.setBusinessId(customerOrderid);
                bScoresTurnover.setBusinessType(AccPaytypeEnum.ORDER.getValue());
                bScoresTurnover.setCost(amount);
                bScoresTurnover.setScore(scores);
                bScoresTurnover.setUserId(userId);
                bScoresTurnover.setUserName(userScores.getUserName());
                bScoresTurnover.setUserType(userType);
                bScoresTurnover.setIsused(false);
                bScoresTurnover.setCreateTime(new Date());
                bScoresTurnover.setUpdateTime(new Date());
                this.getBScoresTurnoverService().insert(bScoresTurnover, false);
            }
        } catch (Exception e) {
            LOGGER.info("select order scores params userId : {}, userType : {}, totalCost : {}, error : {}.", userId, userType, totalCost, e);
            throw new BusinessException("查询用户下单可用积分异常");
        }
        vo.setScores(scores);
        vo.setAmount(amount);
        return vo;
    }

    /**
     * 快速提现
     * 查询手续费(现金抵扣/积分抵扣)
     *
     * @param amount
     * @return
     */
    @Override
    public Map<String, Object> selectWithdrawalFee(BigDecimal amount) {
        LOGGER.info("select quick withdrawal fee params amount : {}.", amount);
        // 查询当前用户
        UserShowVo userShowVo = this.getUserShowVo();
        LOGGER.info("select current user userShowVo : {}.", JSON.toJSONString(userShowVo));
        if (null == userShowVo) {
            LOGGER.info("select current user is not exist userShowVo : {}.", JSON.toJSONString(userShowVo));
            throw new BusinessException("当前登录账户不存在");
        }
        Long userId = userShowVo.getId();
        Integer userType = userShowVo.getUserType();

        Map<String, Object> map = new HashMap<String, Object>();
        try {
            BigDecimal discount = BigDecimal.ZERO;
            map.put("maxscores", QUICKWITHDRAW_SCORES_MAXEXCHANGE.setScale(BIGDECIMAL_TYPE, BIGDECIMAL_POINT)); // 并且不超过500元

            // 查询快速提现手续费
            BActivity activity = bActivityService.getByTypeAndClass(userType, BActivityTypeEnum.USERS_WITHDRAW.getValue(), BActivityClassEnum.DISCOUNT.getValue());
            if (null != activity) {
                discount = activity.getDiscount();
                map.put("rate", new BigDecimal("100").multiply(discount).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE) + "%"); // 快速提现需要支付手续费（千分之二，不封顶）
            }

            BigDecimal fee = amount.multiply(discount).setScale(2, BigDecimal.ROUND_UP);
            map.put("fee", fee);
            map.put("maxrate", new BigDecimal("100").multiply(QUICKWITHDRAW_FEE_MAXEXCHANGE).setScale(0, BIGDECIMAL_TYPE) + "%"); // 可用积分冲抵，单次最多冲抵手续费的20%

            // 查询用户积分
            BScores userScores = this.getUserScores(userId, userType);
            if (null == userScores) {
                map.put("scoresText", "积分共0积分,不能抵扣");
                map.put("scores", BigDecimal.ZERO);
                map.put("subfee", BigDecimal.ZERO);
            } else if (userScores.getScores().compareTo(BigDecimal.ZERO) == 0) {
                map.put("scoresText", "积分共0积分,不能抵扣");
                map.put("scores", BigDecimal.ZERO);
                map.put("subfee", BigDecimal.ZERO);
            } else {
                // 最多抵扣费用 fee*20%
                BigDecimal maxFee = fee.multiply(QUICKWITHDRAW_FEE_MAXEXCHANGE).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                // 最多抵扣积分 fee*20%＊25
                BigDecimal maxFeeScores = maxFee.multiply(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);

                // 共有积分
                BigDecimal scores = userScores.getScores();
                // 2最多抵扣积分 500*25
                BigDecimal max_scoresFee = QUICKWITHDRAW_SCORES_MAXEXCHANGE.multiply(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                // 全部使用积分 积分数 fee*25
                // BigDecimal scoresFee = fee.multiply(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                if (maxFee.compareTo(QUICKWITHDRAW_SCORES_MAXEXCHANGE) == -1) {
                    if (maxFeeScores.compareTo(scores) == 0 || maxFeeScores.compareTo(scores) == -1) {
                        map.put("scoresText", "积分共" + scores + "积分，本次使用" + maxFeeScores + "积分抵扣¥" + maxFee.setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                        // map.put("fee", fee.subtract(maxFee).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                        map.put("scores", maxFeeScores);
                        map.put("subfee", maxFee.setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                    } else {
                        map.put("scoresText", "积分共" + scores + "积分，本次使用" + scores + "积分抵扣¥" + scores.divide(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT, BIGDECIMAL_POINT, BIGDECIMAL_TYPE).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                        // map.put("fee", fee.subtract(scores.divide(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT, BIGDECIMAL_POINT, BIGDECIMAL_TYPE).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE)).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                        map.put("scores", scores);
                        map.put("subfee", scores.divide(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT, BIGDECIMAL_POINT, BIGDECIMAL_TYPE).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                    }
                } else {
                    // 最多抵扣 500元
                    if (max_scoresFee.compareTo(scores) == 0 || max_scoresFee.compareTo(scores) == -1) {
                        map.put("scoresText", "积分共" + scores + "积分，本次使用" + max_scoresFee + "积分抵扣¥" + QUICKWITHDRAW_SCORES_MAXEXCHANGE.setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                        // map.put("fee", fee.subtract(QUICKWITHDRAW_SCORES_MAXEXCHANGE).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                        map.put("scores", max_scoresFee);
                        map.put("subfee", QUICKWITHDRAW_SCORES_MAXEXCHANGE.setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                    } else {
                        map.put("scoresText", "积分共" + scores + "积分，本次使用" + scores + "积分抵扣¥" + scores.divide(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                        // map.put("fee", fee.subtract(scores.divide(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE)).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                        map.put("scores", scores);
                        map.put("subfee", scores.divide(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE));
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.info("select quick withdrawal fee params userId : {}, userType : {}, amount : {}, error : {}.", userId, userType, amount, e);
            throw new BusinessException("查询快速提现手续费异常");
        }
        return map;
    }

    /**
     * 查询托运企业月账单结算
     * 可用积分抵扣的金额
     *
     * @param amount
     * @return
     */
    @Override
    public QueryKyleBillScoresVo selectKyleCompanyBillScores(BigDecimal amount, BigDecimal usedAmount) {
        LOGGER.info("select driver company month bill scores params amount : {}.", amount);
        QueryKyleBillScoresVo vo = new QueryKyleBillScoresVo();
        BigDecimal scores = BigDecimal.ZERO;
        BigDecimal subfee = BigDecimal.ZERO;
        BigDecimal currScores = BigDecimal.ZERO;
        try {
            // 查询当前用户
            UserShowVo userShowVo = this.getUserShowVo();
            LOGGER.info("select current user userShowVo : {}.", JSON.toJSONString(userShowVo));
            if (null == userShowVo) {
                LOGGER.info("select current user is not exist userShowVo : {}.", JSON.toJSONString(userShowVo));
                throw new BusinessException("当前登录账户不存在");
            }
            Long userId = userShowVo.getId();
            Integer userType = userShowVo.getUserType();
            LOGGER.info("select driver company month bill scores params amount : {}, userId : {}, userType : {}.", amount, userId, userType);
            BScores userScores = this.getUserScores(userId, userType);
            // 查询用户积分
            if (userType == UserTypeEnum.COMPANY.getValue() || userType == UserTypeEnum.SCOMPANY.getValue()) {
                userId = this.getBCompanyUserService().getCompanyIdByUserId(userId);
            }

            if (null == userScores || userScores.getScores().compareTo(BigDecimal.ZERO) != 1 || (usedAmount != null && KyleCompany_MonthBill_MaxAmount.compareTo(usedAmount) != 1)) {
                // map.put("scoresText", "积分共0积分,不能抵扣");
                // map.put("scores", BigDecimal.ZERO);
                // map.put("subfee", BigDecimal.ZERO);
                vo.setAmount(subfee);
                vo.setScores(scores);
                vo.setScoresText("积分可抵扣金额¥0.00");
                return vo;
            } else {
                // 当前账户积分余额
                currScores = userScores.getScores();
                // 按照比例 maxRate 最多可抵扣金额
                // BigDecimal maxRate = amount.multiply(KyleCompany_MonthBill_MaxRate).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);

                // maxRate Scores 月账单10% 最多抵扣 去掉
                // BigDecimal maxRateScores = maxRate.multiply(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                // maxAmount Scores
                if (null != usedAmount && KyleCompany_MonthBill_MaxAmount.compareTo(usedAmount) == 1) {
                    KyleCompany_MonthBill_MaxAmount = KyleCompany_MonthBill_MaxAmount.subtract(usedAmount).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                }
                BigDecimal maxAmountScores = KyleCompany_MonthBill_MaxAmount.multiply(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);

                BigDecimal amountScores = amount.multiply(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                if (amountScores.compareTo(maxAmountScores) == 1) {
                    if (maxAmountScores.compareTo(currScores) == 1) {
                        scores = currScores;
                        subfee = currScores.divide(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT, BIGDECIMAL_POINT, BIGDECIMAL_TYPE).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                        ;
                    } else {
                        scores = maxAmountScores;
                        subfee = KyleCompany_MonthBill_MaxAmount;
                    }
                } else {
                    if (amountScores.compareTo(currScores) == 1) {
                        // 使用积分大于当前积分余额 使用当前积分余额
                        scores = currScores;
                        subfee = currScores.divide(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT, BIGDECIMAL_POINT, BIGDECIMAL_TYPE).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                    } else {
                        // 使用最大兑换金额
                        scores = amountScores;
                        subfee = amountScores.divide(QUICKWITHDRAW_SCORES_EXCHANGE_DISCOUNT, BIGDECIMAL_POINT, BIGDECIMAL_TYPE).setScale(BIGDECIMAL_POINT, BIGDECIMAL_TYPE);
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.info("select driver company month bill scores params amount : {}, error : {}.", amount, e);
            throw new BusinessException("查询托运企业月积分可抵扣金额异常");
        }
        if (subfee.compareTo(BigDecimal.ZERO) == 1) {
            vo.setScoresText("积分共" + currScores + "，本次使用" + scores + "积分抵扣¥" + subfee);
        } else {
            vo.setScoresText("积分可抵扣金额¥0.00");
        }
        vo.setScores(scores);
        vo.setAmount(subfee);
        return vo;
    }

    /**
     * 查询用户当前积分
     *
     * @param userId
     * @param userType
     * @return
     */
    @Override
    public BScores selectByUserIdAndUserType(Long userId, Integer userType) {
        LOGGER.info("select bscores by userId and userType params userId : {}, userType : {}.", userId, userType);
        try {
            BScoresExample example = new BScoresExample();
            example.createCriteria().andUserIdEqualTo(userId).andUserTypeEqualTo(userType);
            List<BScores> bScoresList = this.getBScoresMapper().selectByExample(example);
            if (!Collections.isEmpty(bScoresList)) {
                return bScoresList.get(0);
            }
        } catch (Exception e) {
            LOGGER.error("select bscores by userId and userType params userId : {}, userType : {}, error : {}.", userId, userType, e);
            throw new BusinessException("根据用户ID和用户类型查询用户积分异常");
        }
        return null;
    }

    /**
     * 查询托运企业月账单结算
     * 可用积分抵扣的金额
     * －－ 扣除积分
     *
     * @param billId
     * @return
     */
    @Override
    public Result<String> kyleCompanyBillUserScores(Long billId) {
        LOGGER.info("driver company month bill user scores params billId : {}.", billId);
        Result<String> result = new Result<>(true, "使用积分抵扣金额完成");
        try {
            CBill cBill = this.getCAccntBillService().selectByPrimaryKey(billId);
            if (cBill == null) {
                LOGGER.info("driver company month bill user scores params billId : {} no bill.", billId);
                throw new BusinessException("托运企业月结算扣除积分未查询到账单");
            }
            QueryKyleBillScoresVo scoresVo = this.selectKyleCompanyBillScores(cBill.getAmount().abs(), this.getCAccntBillService().getScoresUserdAmount(billId));
            String scoresText = scoresVo.getScoresText();
            if (null == scoresText) {
                LOGGER.info("driver company month bill user scores params billId : {} no scores.", billId);
                throw new BusinessException("托运企业月结算扣除积分未查询到积分");
            }

            Long userId = cBill.getUserId();
            String userName = cBill.getUserName();
            Integer userType = cBill.getUserType();

            BigDecimal scores = scoresVo.getScores();
            BigDecimal amount = scoresVo.getAmount();
            LOGGER.info("driver company month bill user scores insert scores params userId:{}, userName: {}, userType: {}, scores:{}, amount:{}.",
                    userId, userName, userType, scores, amount);
            if (amount.compareTo(BigDecimal.ONE) == 1) {
                LOGGER.info("driver company month bill user scores insert scores params userId:{}, userName: {}, userType: {}, scores:{}, amount:{}.",
                        userId, userName, userType, scores, amount);

                // 更新账单 表中积分抵扣金额
                cBill.setScoresPaid(amount);
                this.getCAccntBillService().updateByParimayKey(cBill);

                // 扣除积分 添加积分明细
                BScoresTurnover bScoresTurnover = new BScoresTurnover();
                bScoresTurnover.setBusinessId(billId);
                bScoresTurnover.setBusinessType(AccPaytypeEnum.BIllSUBFEE.getValue());
                bScoresTurnover.setCost(amount);
                bScoresTurnover.setScore(scores.abs().negate());
                bScoresTurnover.setIsused(true);
                bScoresTurnover.setUserId(userId);
                bScoresTurnover.setUserName(userName);
                bScoresTurnover.setUserType(userType);
                bScoresTurnover.setCreateTime(new Date());
                bScoresTurnover.setUpdateTime(new Date());
                this.getBScoresTurnoverService().insert(bScoresTurnover, true);
            }
        } catch (Exception e) {
            result.setSuccess(false);
            result.setMessage("积分抵扣月账单金额系统异常");
            LOGGER.info("driver company month bill user scores params billId : {}, error : {}.", billId, e);
            throw new BusinessException("托运企业月结算扣除积分异常");
        }
        return result;
    }

}